#ifndef CKKS_SRC_STRING_UTILS_H_
#define CKKS_SRC_STRING_UTILS_H_

#include <complex>

#include "common.h"
#include "ciphertext.h"
#include "context.h"
using namespace std;

class StringUtils {
public:
    // 普通构造函数
    StringUtils() = default;

    // 拷贝构造函数
    StringUtils(const StringUtils &strU) = delete;
    StringUtils &operator = (const StringUtils &strU) = delete;

    // 移动构造函数
    StringUtils(StringUtils &&strU) = delete;
    StringUtils &operator = (StringUtils &&strU) = delete;

    /* *
     * 在控制台中打印数组
     * @param[in] vals: long 类型数组
     * @param[in] size: 数组大小
     */
    static void Show(uint64_t *vals, long size);

    /* *
     * 在控制台中打印数组
     * @param[in] vals: long 类型数组
     * @param[in] size: 数组大小
     */
    static void Show(long *vals, long size);

    /* *
     * 在控制台中打印数组
     * @param[in] vals: double 类型数组
     * @param[in] size: 数组大小
     */
    static void Show(double *vals, long size);

    /* *
     * 在控制台中打印数组
     * @param[in] vals: complex 类型数组
     * @param[in] size: 数组大小
     */
    static void Show(complex<double> *vals, long size);

    /* *
     * 在控制台中打印 val1、val2 和 (val1-val2)
     * @param[in] val1: double 类型值
     * @param[in] val2: double 类型值
     * @param[in] prefix: 字符串前缀
     */
    static void ShowCompare(double val1, double val2, string prefix);

    /* *
     * 在控制台中打印 val1、val2 和 (val1-val2)
     * @param[in] val1: complex 类型值
     * @param[in] val2: complex 类型值
     * @param[in] prefix: 字符串前缀
     */
    static void ShowCompare(complex<double> val1, complex<double> val2, string prefix);

    /* *
     * 在控制台中逐项打印 val1[i]、val2[i] 和 (val1[i]-val2[i])
     * @param[in] vals1: double 类型数组
     * @param[in] vals2: double 类型数组
     * @param[in] size: 数组大小
     * @param[in] prefix: 字符串前缀
     */
    static void ShowCompare(double *vals1, double *vals2, long size, string prefix);

    /* *
     * 在控制台中逐项打印 val1[i]、val2[i] 和 (val1[i]-val2[i])
     * @param[in] vals1: complex 类型数组
     * @param[in] vals2: complex 类型数组
     * @param[in] size: 数组大小
     * @param[in] prefix: 字符串前缀
     */
    static void ShowCompare(complex<double> *vals1, complex<double> *vals2, long size, string prefix);

    static complex<double> ShowCompare1(complex<double> *vals1, complex<double> *vals2, long size, int i);

    /* *
     * 在控制台中逐项打印 val1[i]、val2 和 (val1[i]-val2)
     * @param[in] vals1: double 类型数组
     * @param[in] val2: double 类型值
     * @param[in] size: 数组大小
     * @param[in] prefix: 字符串前缀
     */
    static void ShowCompare(double *vals1, double val2, long size, string prefix);

    /* *
     * 在控制台中逐项打印 val1[i]、val2 和 (val1[i]-val2)
     * @param[in] vals1: complex 类型数组
     * @param[in] val2: complex 类型值
     * @param[in] size: 数组大小
     * @param[in] prefix: 字符串前缀
     */
    static void ShowCompare(complex<double> *vals1, complex<double> val2, long size, string prefix);

    /* *
     * 在控制台中逐项打印 val1、val2[i] 和 (val1-val2[i])
     * @param[in] val1: double 类型值
     * @param[in] vals2: double 类型数组
     * @param[in] size: 数组大小
     * @param[in] prefix: 字符串前缀
     */
    static void ShowCompare(double val1, double *vals2, long size, string prefix);

    /* *
     * 在控制台中逐项打印 val1、val2[i] 和 (val1-val2[i])
     * @param[in] val1: complex 类型值
     * @param[in] vals2: complex 类型数组
     * @param[in] size: 数组大小
     * @param[in] prefix: 字符串前缀
     */
    static void ShowCompare(complex<double> val1, complex<double> *vals2, long size, string prefix);
};

#endif
